package org.linlinjava.litemall.web.config;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.apache.commons.lang3.StringUtils;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.core.util.ResponseUtil.Response;
import org.linlinjava.litemall.db.domain.LitemallToken;
import org.linlinjava.litemall.db.service.LitemallTokenService;
import org.linlinjava.litemall.db.util.SpringUtils;
import org.linlinjava.litemall.web.annotation.support.LoginUserHandlerMethodArgumentResolver;
import org.linlinjava.litemall.web.util.JwtHelper;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.OncePerRequestFilter;

import com.fasterxml.jackson.databind.ObjectMapper;

@Configuration
public class WebConfig {

	/**
	 * token过滤器
	 * @return
	 */
	@Bean
	public FilterRegistrationBean<TokenAuthenticationFilter> tokenAuthenticationFilter() {
		TokenAuthenticationFilter tokenAuthenticationFilter = new TokenAuthenticationFilter();
		FilterRegistrationBean<TokenAuthenticationFilter> filterRegistrationBean = new FilterRegistrationBean<>();
		filterRegistrationBean.setFilter(tokenAuthenticationFilter);
		filterRegistrationBean.addUrlPatterns("/*");
		return filterRegistrationBean;
	}

	/**
	 * token过滤器
	 *
	 * @author kretz
	 *
	 * @versoin 2020年12月17日
	 */
	public static class TokenAuthenticationFilter extends OncePerRequestFilter {

		private static final String[] EXCLUDE_PATH = {
			"/controller/auth/login",
			"/favicon.ico",
			"/captcha.jpg",
			"/error",
			"/images",
			"/javascripts",
			"/web/auth/login",
			"/admin/auth/login",
			"/wx/auth/login",
			"/stylesheets",
			"/swagger-ui.html",
			"/swagger-resources/*",
			"/swagger-resources",
			"/swagger-resources/configuration/ui",
			"/swagger-resources/configuration/security",
			"/doc.html#/*",
			"/doc.html/*",
			"/doc.html",
			"/doc.html#/home",
			"/configuration",
			"/webjars",
			"/v2/api-docs",
			"/csrf"
		};

		private JwtHelper jwtHelper = new JwtHelper();

		private ObjectMapper objectMapper = new ObjectMapper();

		@Override
		protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
				FilterChain filterChain) throws ServletException, IOException {
	        String path = request.getRequestURI().substring(request.getContextPath().length()).replaceAll("[/]+$", "");
	        if (validToken(request)||validPath(path)) {
				/*String token = request.getHeader("i-lumiere-token");
				Integer userId = new JwtHelper().verifyTokenAndGetUserId(token);
				//判断token是否失效 是否被挤下线
				LitemallTokenService litemallTokenService = (LitemallTokenService) SpringUtils.getBean("litemallTokenService");
				LitemallToken litemallToken = litemallTokenService.getOne(Wrappers.lambdaQuery(LitemallToken.class)
						.eq(LitemallToken::getToken, token)
						.eq(LitemallToken::getUserId, userId));
				//失效token已经被清除
				if(ObjectUtil.isNull(litemallToken)){
					if(validPath(path)){
						filterChain.doFilter(request, response);
						return;
					}else {
						return;
					}
				}
				//账号被挤下线或者被系统禁用
				if(litemallToken.getValid()==1||litemallToken.getValid()==2){
					//清除令牌
					litemallTokenService.removeById(litemallToken);
					throw new RuntimeException("5000");
				}
*/
				filterChain.doFilter(request, response);
	        } else {
	        	Response<Object> res = ResponseUtil.unlogin();
	        	response.setContentType("application/json;charset=UTF-8");
	        	String result = objectMapper.writeValueAsString(res);
				response.getWriter().print(result);
	        }
		}

		private boolean validPath(String path) {
			for (int i = 0; i < EXCLUDE_PATH.length; i++) {
				String excludePath = EXCLUDE_PATH[i];
				if (StringUtils.startsWith(path, excludePath)) {
					return true;
				}
			}

			return false;
		}

		private boolean validToken(HttpServletRequest request) {
			 String token = request.getHeader(LoginUserHandlerMethodArgumentResolver.LOGIN_TOKEN_KEY);
			 //内部访问token
			 if(StrUtil.isNotEmpty(token)&&token.equals("yliyunToken")){
				 /*//判断token是否失效 是否被挤下线
				 LitemallTokenService litemallTokenService = (LitemallTokenService) SpringUtils.getBean("litemallTokenService");
				 LitemallToken litemallToken = litemallTokenService.getOne(Wrappers.lambdaQuery(LitemallToken.class)
						 .eq(LitemallToken::getToken, token));
				 //失效token已经被清除
				 if(ObjectUtil.isNull(litemallToken)){
					 return false;
				 }
				 //账号被挤下线或者被系统禁用
				 if(litemallToken.getValid()==1||litemallToken.getValid()==2){
					 litemallTokenService.removeById(litemallToken);
					 //优化后需要主动向前端推送消息「提醒他已经被踢下线，并且刷新页面」
					 return false;
				 }*/
				 return true;
			 }
			 return jwtHelper.verifyToken(token);
		}

	}

}
